package it.polimi.swKnights.SWIMv2.ejb.authentication;

import it.polimi.swKnights.SWIMv2.ejb.administration.BannedUtilityLocal;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.BannedUser;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.RegisteredUser;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.InvalidLoginPrivilegesException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.LoginFailException;
import it.polimi.swKnights.SWIMv2.utility.PasswordUtility;

import java.util.Date;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 * Session Bean implementation class LoginHandlerBean
 */
@Stateless
public class LoginHandler implements LoginHandlerRemote, LoginHandlerLocal
{

	@PersistenceContext(unitName = "swimv2-manager")
	private EntityManager manager; // manager handlin the persistence data

	@EJB
	private BannedUtilityLocal bannedUtility;

	private PasswordUtility pu;

	/**
	 * - Default constructor.
	 */
	public LoginHandler()
	{
		pu = new PasswordUtility();
	}

	public void checkLoginData(String userName, String password)
			throws LoginFailException
	{
		this.checkValidParameters(userName, password);
		this.checkEndBan(userName);

		RegisteredUser foundUser = manager.find(RegisteredUser.class, userName);

		if (foundUser != null)
		{
			checkPassword(password, foundUser);
		}
		else
		{
			throw new LoginFailException();
		}

	}

	@Override
	public <T extends RegisteredUser> void checkLoginDataAndPrivileges(
			String userName, String password, Class<T> clazz)
			throws LoginFailException, InvalidLoginPrivilegesException
	{
		this.checkLoginData(userName, password);
		if (!this.hasPrivileges(userName, clazz))
			throw new InvalidLoginPrivilegesException();
	}

	@Override
	public boolean hasPrivileges(String userName,
			Class<? extends RegisteredUser> clazz)
	{
		if (userName == null)
			return false;
		if (this.manager.find(clazz, userName) != null)
		{
			return true;
		}
		else
			return false;
	}

	@Override
	public void checkBanned(String userName)
			throws InvalidLoginPrivilegesException
	{
		if (this.hasPrivileges(userName, BannedUser.class))
		{
			throw new InvalidLoginPrivilegesException();
		}
	}

	private void checkPassword(String password, RegisteredUser ru)
			throws LoginFailException
	{
		String storedHashPasswd = ru.getPasswordHash();
		String userMail = ru.geteMail();
		if (!(pu.autenticate(password, storedHashPasswd, userMail)))
		{
			throw new LoginFailException();
		}
	}

	private void checkValidParameters(String userName, String password)
			throws LoginFailException
	{
		if (userName == null | password == null)
			throw new LoginFailException();

	}

	private void checkEndBan(String userName)
	{
		BannedUser banned = this.manager.find(BannedUser.class, userName);

		if (banned != null)
		{
			Date endOfBan = banned.getEndOfBan();
			Date today = new Date();
			
			if (today.after(endOfBan))
			{
				this.bannedUtility.endBanUser(banned);
			}
		}

	}

}
